package base.model;

import base.encoder.IDecoder;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 消息解码
 * Created by wuhui on 2016/8/4.
 */
@Slf4j
public class NettyMessageDecoder extends LengthFieldBasedFrameDecoder {

    IDecoder iDecoder ;

    public NettyMessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) {
        //数据长度所在字节的位置lengthFieldOffset
        //lengthFieldLength 数据长度本身所占的长度数
        //lengthAdjustment 长度调节值，在总长被定义为包含包头长度时，修正信息长度
        super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
        this.iDecoder = iDecoder;
    }

    public NettyMessageDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength) {
        super(maxFrameLength, lengthFieldOffset, lengthFieldLength);
        iDecoder = null;
    }
    //消息解码
    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
//        byte[] bytes = new byte[100];
//        in.readBytes(bytes);
//        System.out.println(new String(bytes));
        //调用父类根据包的长度进行包的拆包粘包处理
        ByteBuf in = (ByteBuf) super.decode(ctx,byteBuf);
        if(in == null){
            return  null;
        }
        NettyMessage nettyMessage = new NettyMessage();
        Header header = new Header();
        header.setCrcCode(in.readInt());
        header.setLength(in.readInt());
        header.setSessionId(in.readLong());
        header.setType(in.readByte());
        header.setPriority(in.readByte());
        int size = in.readInt();
        if(size>0){
            Map<String,Object> attch = new HashMap<>(size);
            int keySize = 0;
            byte[] keyArray = null;
            String key = null;
            for (int i = 0; i < size; i++) {
                keySize =in.readInt();
                keyArray  = new byte[keySize];
                key = new String(keyArray,"UTF-8");
                attch.put(key,iDecoder.decode(in));
            }
            key = null;
            keyArray = null;
            header.setAttachment(attch);
            if(in.readableBytes()>4){
                nettyMessage.setBody(iDecoder.decode(in));
            }
        }
        nettyMessage.setHeader(header);
        return  nettyMessage;
    }
}
